package com.weimin.ghostdrop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.weimin.ghostdrop.entity.Image;
import com.weimin.ghostdrop.entity.Links;
import com.weimin.ghostdrop.entity.Software;
import com.weimin.ghostdrop.entity.dto.LinksDTO;
import com.weimin.ghostdrop.entity.dto.SoftwareDTO;
import com.weimin.ghostdrop.entity.vo.SoftwareDetailVO;
import com.weimin.ghostdrop.entity.vo.SoftwareListVO;
import com.weimin.ghostdrop.mapper.ImageMapper;
import com.weimin.ghostdrop.mapper.LinksMapper;
import com.weimin.ghostdrop.service.SoftwareService;
import com.weimin.ghostdrop.mapper.SoftwareMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
* @author huimin
* @description 针对表【software(软件信息表)】的数据库操作Service实现
* @createDate 2025-10-11 10:32:07
*/
@Service
@RequiredArgsConstructor
public class SoftwareServiceImpl extends ServiceImpl<SoftwareMapper, Software> implements SoftwareService {

    private final ImageMapper imageMapper;
    private final LinksMapper linksMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createSoftware(SoftwareDTO dto) {
        // 保存软件
        Software s = new Software();
        BeanUtils.copyProperties(dto, s);
        // 后端生成四位编号 code（0000-9999）
        s.setCode(generateUniqueCode());
        Date now = new Date();
        s.setCreatedAt(now);
        s.setUpdatedAt(now);
        this.save(s);
        Integer sid = s.getId();

        // 批量写入图片（按顺序设置 orderIndex）
        if (dto.getImageUrls() != null && !dto.getImageUrls().isEmpty()) {
            List<Image> images = new ArrayList<>();
            int idx = 0;
            for (String url : dto.getImageUrls()) {
                if (url == null || url.isBlank()) continue;
                Image img = new Image();
                img.setSid(sid);
                img.setUrl(url);
                img.setOrderIndex(idx++);
                img.setCreatedAt(now);
                images.add(img);
            }
            if (!images.isEmpty()) {
                images.forEach(imageMapper::insert);
            }
        }

        // 写入 links（单行）
        LinksDTO l = dto.getLinks();
        if (l != null) {
            Links links = new Links();
            links.setSid(sid);
            links.setBaidu(l.getBaidu());
            links.setAliyun(l.getAliyun());
            links.setXunlei(l.getXunlei());
            links.setQuark(l.getQuark());
            links.setLanzou(l.getLanzou());
            links.setCreatedAt(now);
            linksMapper.insert(links);
        }

        return sid;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSoftware(Integer id, SoftwareDTO dto) {
        Software exist = this.getById(id);
        if (exist == null) {
            throw new IllegalArgumentException("Software not found: " + id);
        }
        // 更新基础信息
        BeanUtils.copyProperties(dto, exist, "id", "createdAt", "updatedAt");
        exist.setUpdatedAt(new Date());
        this.updateById(exist);

        // 覆盖 images（若提供）
        if (dto.getImageUrls() != null) {
            // 先删旧
            imageMapper.delete(new LambdaQueryWrapper<Image>().eq(Image::getSid, id));
            // 再插入新
            Date now = new Date();
            List<Image> images = new ArrayList<>();
            int idx = 0;
            for (String url : dto.getImageUrls()) {
                if (url == null || url.isBlank()) continue;
                Image img = new Image();
                img.setSid(id);
                img.setUrl(url);
                img.setOrderIndex(idx++);
                img.setCreatedAt(now);
                images.add(img);
            }
            images.forEach(imageMapper::insert);
        }

        // 覆盖 links（若提供）
        if (dto.getLinks() != null) {
            LinksDTO l = dto.getLinks();
            Links links = linksMapper.selectOne(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Links>().eq("sid", id));
            if (links == null) {
                links = new Links();
                links.setSid(id);
                links.setCreatedAt(new Date());
                links.setBaidu(l.getBaidu());
                links.setAliyun(l.getAliyun());
                links.setXunlei(l.getXunlei());
                links.setQuark(l.getQuark());
                links.setLanzou(l.getLanzou());
                linksMapper.insert(links);
            } else {
                links.setBaidu(l.getBaidu());
                links.setAliyun(l.getAliyun());
                links.setXunlei(l.getXunlei());
                links.setQuark(l.getQuark());
                links.setLanzou(l.getLanzou());
                linksMapper.updateById(links);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSoftware(Integer id) {
        // 删从表
        imageMapper.delete(new LambdaQueryWrapper<Image>().eq(Image::getSid, id));
        linksMapper.delete(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Links>().eq("sid", id));
        // 删主表
        this.removeById(id);
    }

    @Override
    public IPage<SoftwareListVO> pageWithCover(Page<?> page, String title, String code) {
        return this.baseMapper.pageWithCover(page, emptyToNull(title), emptyToNull(code));
    }

    @Override
    public SoftwareDetailVO detail(Integer id) {
        Software s = this.getById(id);
        if (s == null) {
            throw new IllegalArgumentException("Software not found: " + id);
        }
        List<Image> imgs = imageMapper.selectList(new LambdaQueryWrapper<Image>()
                .eq(Image::getSid, id)
                .orderByAsc(Image::getOrderIndex, Image::getId));
        List<String> urls = new ArrayList<>();
        for (Image img : imgs) {
            if (img.getUrl() != null) urls.add(img.getUrl());
        }
        SoftwareDetailVO vo = new SoftwareDetailVO();
        vo.setSoftware(s);
        vo.setImages(urls);
        return vo;
    }

    private String emptyToNull(String s) {
        return (s == null || s.isBlank()) ? null : s;
    }

    // 生成唯一四位数字编号（字符串，左侧零填充）
    private String generateUniqueCode() {
        for (int i = 0; i < 50; i++) {
            int num = ThreadLocalRandom.current().nextInt(0, 10000);
            String code = String.format("%04d", num);
            long cnt = this.lambdaQuery().eq(Software::getCode, code).count();
            if (cnt == 0) {
                return code;
            }
        }
        throw new IllegalStateException("生成唯一编号失败，请重试");
    }
}




